import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.stream.Stream;

/****
 * 一、Stream的三个步骤
 * 1.创建Stream
 * 2.中间操作
 * 3.终止操作(终端操作)
 * 
 * @author Administrator
 *
 */
public class TestStreamAPI2 {
	   List<Employee> employees= Arrays.asList(
			     new Employee("张三",18,9999.99),
			     new Employee("李四",38,5555.99),
			     new Employee("王五",50,66666.66),
			     new Employee("赵六",16,3333.33),
			     new Employee("田七",8,7777.77),
			     new Employee("田七",8,7777.77)

	   );
	   
	   //中间操作
	   /*
	    * 筛选和切片
          filter(Predicate p)        接收Lambda，从流中排出不符合的某些元素
         distinct()                 筛选,通过流所生成元素的hashcode()和equals(),去除重复元素
         limit(long maxsize)       截断流，使元素不会超过指定的数量。
         skip(long n) 跳过元素，返回了一个扔掉了前n个元素的流，若流不足n个元素，则返回一个空流，与limit互补，
一个跳过前面 一个扔掉后面
*
* 映射
* map-接收Lambda，将元素转换成其他形式或提取信息。接收一个函数作为参数，该函数会被应用到每个元素上，并将其映射成一个新的元素。flatMap-接收一个函数作为参数，
* 将流中的每个值都换成另一个流，然后把所有流连接成一个流
*
* 排序
* sorted()-自然(默认)排序(Comparable.compareTo()接口)
* sorted(Comparator com)-定制排序(Comparator.compare()接口)
*
*  */

	//内部迭代:迭代操作由StreamAPI完成
	@Test
	public void test1(){
		//中间操作,执行终止操作才会执行，即"惰性求值"
		Stream<Employee> stream=employees.stream().filter(
				//filter里面是断言函数接口 ，忘了什么参数可以具看下
				(e)->{
					System.out.println("Stream API 的中间操作");
					return  e.getAge()>35;
				}
		);

		//终止操作,执行终止操作中间操作才会执行，System.out::println相当于(x)->
		// System,out.println(x),是方法引用
		stream.forEach(System.out::println);

	}

//截断流 limit截取满足条件的前两个，后面的直接放弃，这样一定程度上提高了效率，找到符合的条件后续操作不再进行
	@Test
	public void test3(){
		employees.stream().filter((e)->{
			System.out.println("短路");
			return  e.getSalary()>5000;}
			).limit(2).
				forEach(System.out::println);
	}
	//跳过元素  与limit相反 取后面的元素，如果取相同条件的数据效率低于Limit,这个是前面的都得执行
	@Test
	public  void test4(){
     employees.stream().filter((e)->{
     	System.out.println("skip");
     	return  e.getSalary()>5000;
     }).skip(2).forEach(System.out::println);
	}
	//distinct()筛选,通过流所生成元素的hashcode()和equals(),去除重复元素
	@Test
	public  void test5(){
     employees.stream().filter((e)->e.getSalary()>5000).distinct().forEach(System.out::println);
	}

	/***
	 映射
	 * map-接收Lambda，将元素转换成其他形式或提取信息。接收一个函数作为参数，该函数会被应用到每个元素上，并将其映射成一个新的元素。
	 * flatMap-接收一个函数作为参数，将流中的每个值都换成另一个流，然后把所有流连接成一个流
	 */
	@Test
	public  void test6(){
		//抽取出集合元素 aaa、bbb、ccc、ddd、eee抽取出一个单独的元素传入map函数中，作为一个map流中的元素，
		List<String>list=Arrays.asList("aaa","bbb","ccc","ddd","eee");
		list.stream().map((str)->str.toUpperCase()).forEach(System.out::println);
		System.out.println("-------------------------");
		//将employees中姓名抽取出来作为一个流，返回的并非一个map而是一个流
		employees.stream().map(Employee::getName).forEach(System.out::println);

		System.out.println("----------------------------------");
		Stream<Stream<Character>>stream=list.stream().map(TestStreamAPI2::filterCharacter);
		//等价于
		Stream<Stream<Character>>stream1=list.stream().map((x)->filterCharacter(x));

		stream.forEach((sm)->sm.forEach(System.out::println));

		System.out.println("-------------------flatMap-----------------------");

		Stream<Character>sm=list.stream().flatMap(TestStreamAPI2::filterCharacter);
		sm.forEach(System.out::println);

	}

	public  static Stream<Character>filterCharacter(String str){
		List<Character> list =new ArrayList<>();
		for(Character ch:str.toCharArray()){
			list.add(ch);
		}
		return  list.stream();
	}
	/*排序
* sorted()-自然(默认)排序(Comparable.compareTo()接口)
			* sorted(Comparator com)-定制排序(Comparator.compare()接口)*/
	@Test
	public  void test7(){
     List<String>list =Arrays.asList("ccc","aaa","bbb");
     list.stream().sorted().forEach(System.out::println);

     System.out.println("=========定制排==========");
     employees.stream().sorted((e1,e2)->{
     	return  e1.getAge().compareTo(e2.getAge());
	 }).forEach(System.out::println);

	}

}
